package com.xnyzc.lhy.common.component.payment;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.xnyzc.lhy.common.constant.PayConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;

/**
 * @Description 支付宝工具类
 * @Author 刘举
 * @Date 2019/8/7 11:19
 **/
@Slf4j
@Component
public class AliPay {

    private static String aliAppId;

    private static String aliPublicKey;

    private static String aliPrivateKey;

    private static String aliPaySeller;

    private static String apiDomain;

    private static String signType = "RSA2";

    private static String goodsType = "1";

    private static String format = "json";

    private static String charset = "utf-8";


    @Value("${global.ali.pay.appId}")
    public void setAppId(String appId) {
        aliAppId = appId;
    }

    @Value("${global.ali.pay.payPublicKey}")
    public void setPayPublicKey(String payPublicKey) {
        aliPublicKey = payPublicKey;
    }

    @Value("${global.ali.pay.payPrivateKey}")
    public void setPayPrivateKey(String payPrivateKey) {
        aliPrivateKey = payPrivateKey;
    }

    @Value("${global.ali.pay.paySeller}")
    public void setPaySeller(String paySeller) {
        aliPaySeller = paySeller;
    }

    @Value("${global.apiDomain}")
    public void setApiDomain(String domain) {
        apiDomain = domain;
    }

    /**
     * 支付宝支付
     *
     * @param orderNo      订单号
     * @param orderSubject 订单标题
     * @param totalAmount  订单总金额
     * @param passBackJson 公共回传参数（若无，填null）
     * @return
     */
    public static String getAliPayParam(String orderNo, String orderSubject, String totalAmount, JSONObject passBackJson) {

        // 实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(PayConstant.ALI_PAY_URL, aliAppId, aliPrivateKey, format, charset, aliPublicKey, signType);

        // 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        // SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

        model.setSubject(orderSubject);
        model.setGoodsType(goodsType);
        model.setOutTradeNo(orderNo);
        model.setTimeoutExpress("30m");
        model.setSellerId(aliPaySeller);
        model.setTotalAmount(totalAmount);
        model.setProductCode("QUICK_MSECURITY_PAY");

        // 公共回传参数
        passBackJson.put("orderNo", orderNo);

        try {
            model.setPassbackParams(URLEncoder.encode(passBackJson.toJSONString(), charset));
        } catch (UnsupportedEncodingException e) {
            log.error("支付宝支付，公共回传参数编码失败，订单号：{}", orderNo);
        }

        request.setBizModel(model);
        request.setNotifyUrl(apiDomain + PayConstant.ALI_NOTIFY_URL);

        // 返回结果
        String result = "";
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            result = response.getBody();
        } catch (AlipayApiException e) {
            log.error("支付宝支付，生成APP支付订单信息失败，订单号：{}", orderNo);
        }
        return result;
    }

    /**
     * @param orderNo      订单支付时传入的商户订单号
     * @param tradeNo      支付宝交易号
     * @param refundAmount 退款金额
     * @return Boolean
     * @throws AlipayApiException
     * @方法名称:payRefund
     * @内容摘要: ＜退款＞
     */
    public static Boolean aliPayRefundRequest(String orderNo, String tradeNo,
                                              BigDecimal refundAmount) throws AlipayApiException {
        Boolean flag = false;

        AlipayClient alipayClient = new DefaultAlipayClient(PayConstant.ALI_PAY_URL, aliAppId, aliPrivateKey, format, charset, aliPublicKey, signType);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();


        request.setBizContent("{" +
                "    \"out_trade_no\":\"" + orderNo + "\"," +
                "    \"trade_no\":\"" + tradeNo + "\"," +
                "    \"refund_amount\":\"" + refundAmount + "\"," +
                "    \"refund_reason\":\"正常退款\"" +
                "  }");
        AlipayTradeRefundResponse response = alipayClient.execute(request);

        if (response.isSuccess()) {
            flag = true;
        } else {
            log.error("支付宝退款失败,订单号：{}", orderNo);
        }
        return flag;
    }


}

